import json
import os
import threading
import math

class agvRobot:
    def __init__(self, id, x, y, map, timeout,charge):
        self.id = id
        self.x = x
        self.y = y
        self.map = map
        self.timeout = timeout
        self.charge=charge

    def to_dict(self):
        return {
            'id': self.id,
            'x': self.x,
            'y': self.y,
            'map': self.map,
            'timeout': self.timeout,
            'charge': self.charge
        }
    
    def distance_to(self, x, y):
        return math.sqrt((self.x - x) ** 2 + (self.y - y) ** 2)

    @staticmethod
    def from_dict(data):
        return agvRobot(data['id'], data['x'], data['y'], data['map'], data['timeout'],data['charge'])

class agvRobotList:
    def __init__(self, filename='robots.json',interval=1):
        self.filename = filename
        self.robots = []
        self.load_robots()
        self.interval=interval
        # 创建定时器任务
        threading.Timer(self.interval, self.run_task).start()

    def run_task(self):
        # 每10s超时时间减一
        for index,robot in enumerate(self.robots):
            self.robots[index].timeout-=1
            if self.robots[index].timeout<0:
                self.robots[index].timeout=0
        self.save_robots()
        # 重新设置定时器，实现周期性执行
        threading.Timer(self.interval, self.run_task).start()

    def add_robot(self, robot):
        if isinstance(robot, agvRobot):
            self.robots.append(robot)
            self.robots.sort(key=lambda x: x.id)
            self.save_robots()
        else:
            raise TypeError("Only agvRobot instances can be added to the list")
    
    def update_robot(self, robot):
        index = self.get_robot_index_by_id(robot.id)
        if index is not None:
            self.robots[index] = robot
            self.save_robots()
        else:
            self.add_robot(robot)

    def get_robot_index_by_id(self, robot_id):
        for index, robot in enumerate(self.robots):
            if robot.id == robot_id:
                return index
        return None

    def get_json(self):
        return json.dumps([robot.to_dict() for robot in self.robots])

    def save_robots(self):
        with open(self.filename, 'w') as file:
            json.dump([robot.to_dict() for robot in self.robots], file, indent=4)

    def load_robots(self):
        if os.path.exists(self.filename):
            with open(self.filename, 'r') as file:
                robots_data = json.load(file)
                self.robots = [agvRobot.from_dict(data) for data in robots_data]
    
    def find_closest_robot_with_charge_not_expired(self, target_map, target_x, target_y):
        filtered_robots = [
            robot for robot in self.robots
            if robot.map == target_map and robot.timeout != 0 and robot.charge==False
        ]
        if not filtered_robots:
            return None  # 如果没有符合条件的机器人，则返回None

        # 使用min函数和key参数来找出距离最近的机器人
        closest_robot = min(filtered_robots, key=lambda robot: robot.distance_to(int(target_x), int(target_y)))
        return closest_robot
